/*
 *  tsmarray.h
 *  Untitled
 *
 *  Created by Todd Vorisek on 11/12/11.
 *  Copyright 2011 __MyCompanyName__. All rights reserved.
 *
 */

#ifndef _TSM_ARRAY_
#define _TSM_ARRAY_	

#include <iostream>
#include <algorithm>

template<typename Type>
class TSmArray
{
public:
	
	typedef Type value_type;
	typedef Type * iterator;
	typedef const Type * const_iterator;
	typedef std::size_t size_type;	
	
	
	void print();
	
	TSmArray();
	TSmArray( const TSmArray&);
	TSmArray & operator=(const TSmArray&);
	~TSmArray();
	
	explicit TSmArray(size_type);
	
	value_type & operator[](size_type index);
	const value_type & operator[](size_type index) const;
	
	size_type size() const;
	bool empty() const;
	void resize(size_type newsize);
	iterator insert(iterator i, const value_type &);
	iterator remove(iterator i);
	
	iterator begin();
	const_iterator begin() const;
	
	iterator end();
	const_iterator end() const;
	
	void swap(TSmArray &);
	
	
private:
	size_type    _size;
	size_type    _capacity;
	value_type * _data;
};

//TSmArray, default ctor
//basic guarantee
template<typename Type>
TSmArray<Type>::TSmArray():_size(0),_capacity(0),_data(new value_type [_capacity])
{

}

//TSmArray, copy ctor
//basic guarantee (becuase value_type is Type, not built in)
template<typename Type>
TSmArray<Type>::TSmArray(const TSmArray &rhs)
:_size(rhs.size()),_capacity(_size),_data(new value_type [_capacity])
{
	std::copy(rhs.begin(),rhs.end(),begin());
}

//assignment opperator
//Strong guarantee
template<typename Type>
TSmArray<Type> & TSmArray<Type>::operator=(const TSmArray &rhs)
{
	TSmArray temp(rhs);
	swap(temp);
	return *this;
}

//dctor
//No-throw guarantee
template<typename Type>
TSmArray<Type>::~TSmArray()
{
	delete [] _data;
}

//TSmArray, 1 param ctor
//basic guarantee
template<typename Type>
TSmArray<Type>::TSmArray(size_type size)
:_size(size),_capacity(_size),_data(new value_type [_capacity])
{
}


//No-throw guarantee
template<typename Type>
typename TSmArray<Type>::value_type & TSmArray<Type>::operator[](size_type index)
{
	return _data[index];
}

//No-throw guarantee
template<typename Type>
const typename TSmArray<Type>::value_type & TSmArray<Type>::operator[](size_type index) const
{
	return _data[index];
}

//No-throw guarantee
template<typename Type>
typename TSmArray<Type>::size_type TSmArray<Type>::size() const
{
	return _size;
}

//No-throw guarantee
template<typename Type>
bool TSmArray<Type>::empty() const
{
	return _size==0;
}

//No-throw guarantee
template<typename Type>
typename TSmArray<Type>::iterator TSmArray<Type>::begin()
{
	return _data;
}

//No-throw guarantee
template<typename Type>
typename TSmArray<Type>::const_iterator TSmArray<Type>::begin() const
{
	return _data;
}

//No-throw guarantee
template<typename Type>
typename TSmArray<Type>::iterator TSmArray<Type>::end()
{
	return begin()+_size;
}

//No-throw guarantee
template<typename Type>
typename TSmArray<Type>::const_iterator TSmArray<Type>::end() const
{
	return begin()+_size;
}

template<typename Type>
void TSmArray<Type>::resize(size_type newSize)
{
	if (newSize<=_capacity) {
		_size=newSize;
	}
	else{
		TSmArray<Type> temp(newSize*2);
		temp._size = newSize;
		std::copy(begin(),end(), temp.begin());
		
		
		
		swap(temp);
	}
} 

template<typename Type>
typename TSmArray<Type>::iterator TSmArray<Type>::insert(iterator i, const value_type & dataNew)
{
	iterator temp=i;
	std::cout << " pre resize: ";
	print();
	resize(_size+1);
	std::cout << " post resize: ";
	print();
	_data[_size-1] = dataNew;
	 std::rotate(i, end()-1, end());
	return i;
}

template<typename Type>
typename TSmArray<Type>::iterator TSmArray<Type>::remove(iterator i)
{
	std::rotate(i, i+1, end());
	std::cout << "hi!" << std::endl;
	resize(_size-1);

	return i;
}

//no-throw guarantee
template<typename Type>
void TSmArray<Type>::swap(TSmArray<Type> &rhs)
{
	std::swap(_size,rhs._size);
	std::swap(_capacity, rhs._capacity);
	std::swap(_data,rhs._data);
}

template<typename Type>
void TSmArray<Type>::print()
{
	for (int j=0; j<_size; j++) {
		std::cout<<_data[j]<<", ";
	}
	std::cout<<std::endl;
}


#endif //_TSM_ARRAY_